/**************************************************************************
 *
 *        Copyright (c) 2008-2008 by Sunplus mMedia Inc., Ltd.
 *
 *  This software is copyrighted by and is the property of Sunplus
 *  mMedia Inc., Ltd. All rights are reserved by Sunplus mMedia
 *  Inc., Ltd. This software may only be used in accordance with the
 *  corresponding license agreement. Any unauthorized use, duplication,
 *  distribution, or disclosure of this software is expressly forbidden.
 *
 *  This Copyright notice MUST not be removed or modified without prior
 *  written consent of Sunplus mMedia Inc., Ltd.
 *
 *  Sunplus mMedia Inc., Ltd. reserves the right to modify this
 *  software without notice.
 *
 *  Sunplus mMedia Inc., Ltd.
 *  19-1, Innovation First Road, Science-Based Industrial Park,
 *  Hsin-Chu, Taiwan, R.O.C.
 *
 **************************************************************************/
/**
 * @file		disp_gp_54124a_lcm.c
 * @brief		display lcm giant plus 54124a driver.
 * @author		Matt Wang
 * @since		2008-06-16
 * @date		2008-08-19
 */

/**************************************************************************
 *                            H E A D E R   F I L E S
 **************************************************************************/
#include "general.h"
#include "disp_api.h"
#include "sp1k_util_api.h"

/**************************************************************************
 *                              C O N S T A N T S
 **************************************************************************/
/* render dimension. */
#define DEV_TYPE   DISP_DEVICE_TYPE_LCM
#define WIDTH      320
#define HEIGHT     240
#define HSYNCW     1
#define VSYNCW     1
#define HPIXEL     360//420
#define VLINE      250//262
#define PNLH0      11
#define PNLV0      5
#define PNLH1      (PNLH0 + WIDTH - 1)
#define PNLV1      (PNLV0 + HEIGHT - 1)

/* clock config. */
#define CLK_SRC        DISP_CLK_SRC_SYSPLL96M
#define CLK_DIVNX      24
#define CLK_DIV1X      2///3
#define UPS_CLK_PHASE  8

/* lcm interface. */
#define BUS_TYPE       DISP_LCM_CMD_BUS_I80
#define BIT_WIDTH      DISP_LCM_CMD_8_9_BIT
#define PULSE_ACT      5
#define PULSE_RCV      4
#define CS0_ACT        0
#define A0_CMD         0
#define DATA_FMT       DISP_LCM_DATA_FMT_RGB565
#define RGB666_PACK    0
#define RGB666_FMT_10  0
#define PIXEL_ALIGN    DISP_LCM_PIXEL_ALIGN_NONE
#define COLOR_PACKAGE  DISP_LCM_COLOR_PACKAGE_RGB
#define SWITCH_G       1
#define CHANGE_RB      0
#define ONE_HALF_PIXEL 0
#define DITHER         1

/**************************************************************************
 *                                  M A C R O S
 **************************************************************************/
/* function type definition. */
#define __STATIC  //static

/* operating function. */
#define dispOpDevNameGet     dispPanelOpDevNameGet
#define dispOpCapabilityGet  dispPanelOpCapabilityGet
#define dispOpPowerOn        dispPanelOpPowerOn
#define dispOpPowerOff       dispPanelOpPowerOff

/**************************************************************************
 *                  F U N C T I O N   D E C L A R A T I O N S
 **************************************************************************/
/* operating function. */
__STATIC UINT8 *dispOpDevNameGet(void);
__STATIC void dispOpCapabilityGet(dispCapabDesc_t *pcapabDesc);
__STATIC void dispOpPowerOn(void);
__STATIC void dispOpPowerOff(void);

/**************************************************************************
 *                            G L O B A L   D A T A
 **************************************************************************/
/* device name. */
static code UINT8 dispDevName[] = "LCD - UC 8230S LCM";

/* device capability. */
static code dispCapabDesc_t dispCapabDesc = {
	WIDTH,
	HEIGHT,
	PNLH0,
	PNLV0,
	4,
	3,
};
static code UINT32 dispPwrOnCmdTbl[] = {
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x01,  
	DISP_LCM_CMD_WAIT |200,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0001, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x00,  
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0003, DISP_LCM_CMD_PARA|0x10,DISP_LCM_CMD_PARA|0x30,  
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0010, DISP_LCM_CMD_PARA|0x17,DISP_LCM_CMD_PARA|0x90,  
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0060, DISP_LCM_CMD_PARA|0x27,DISP_LCM_CMD_PARA|0x00,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0061, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x01,  
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0046, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x02,  
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0013, DISP_LCM_CMD_PARA|0x8c,DISP_LCM_CMD_PARA|0x10,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0012, DISP_LCM_CMD_PARA|0x80,DISP_LCM_CMD_PARA|0xfe,  
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0002, DISP_LCM_CMD_PARA|0x05,DISP_LCM_CMD_PARA|0x00,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0003, DISP_LCM_CMD_PARA|0x10,DISP_LCM_CMD_PARA|0x18,//30	

	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0030, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,	 
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0031, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,	   
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0032, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,	 
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0033, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x00,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0034, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x03,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0035, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0036, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x14,
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0037, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,	// 
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0038, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0039, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x003a, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x00,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x003b, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x03,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x003c, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x003d, DISP_LCM_CMD_PARA|0x14,DISP_LCM_CMD_PARA|0x00,//

	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0092, DISP_LCM_CMD_PARA|0x02,DISP_LCM_CMD_PARA|0x00,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0093, DISP_LCM_CMD_PARA|0x03,DISP_LCM_CMD_PARA|0x03,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0090, DISP_LCM_CMD_PARA|0x08,DISP_LCM_CMD_PARA|0x0d,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0007, DISP_LCM_CMD_PARA|0x01,DISP_LCM_CMD_PARA|0x73,//

	//zhenglei add
	//DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0020, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x00,//
	//DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0021, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x00,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0050, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x00,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0051, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0xEF,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0052, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x00,//
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0053, DISP_LCM_CMD_PARA|0x01,DISP_LCM_CMD_PARA|0x3F,//
	//zhenglei add end
	
	DISP_LCM_CMD_INST|0x0000, DISP_LCM_CMD_INST|0x0022, DISP_LCM_CMD_PARA|0x00,DISP_LCM_CMD_PARA|0x00,//

	DISP_LCM_CMD_WAIT |50,//zhenglei
	DISP_LCM_CMD_STOP,
};

static code UINT32 dispPwrOffCmdTbl[] = {
	
	   DISP_LCM_CMD_STOP,
	
};

/**
 * @brief	open device (register operating function).
 * @param	None.
 * @retval	return = NULL or device id.
 * @see
 * @author	Matt Wang
 * @since	2008-06-16
 * @todo	N/A
 * @bug		N/A
*/
UINT8
dispPanelOpen(
	void
)
{
	dispOperatingFunc_t dispOpFunc;


	dispOpFunc.pfOpDevNameGet    = dispOpDevNameGet;
	dispOpFunc.pfOpCapabilityGet = dispOpCapabilityGet;
	dispOpFunc.pfOpPowerOn       = dispOpPowerOn;
	dispOpFunc.pfOpPowerOff      = dispOpPowerOff;

	return dispDevOpen(&dispOpFunc, sizeof(dispOperatingFunc_t));
}

/**
 * @brief	operating function to get device name (ascii string).
 * @param	None.
 * @retval	return = device name string.
 * @see
 * @author	Matt Wang
 * @since	2008-06-16
 * @todo	N/A
 * @bug		N/A
*/
__STATIC UINT8 *
dispOpDevNameGet(
	void
)
{
	return dispDevName;
}

/**
 * @brief	operating function to get device capability.
 * @param	*pcapabDesc = [out] capability describer.
 * @param   descSize = [in] describer structure size.
 * @retval	None.
 * @see
 * @author	Matt Wang
 * @since	2008-06-16
 * @todo	N/A
 * @bug		N/A
*/
__STATIC void
dispOpCapabilityGet(
	dispCapabDesc_t *pcapabDesc
)
{
	*pcapabDesc = dispCapabDesc;
}

/**
 * @brief	operating function to power on device.
 * @param	None.
 * @retval	None.
 * @see
 * @author	Matt Wang
 * @since	2008-06-16
 * @todo	N/A
 * @bug		N/A
*/
void sp1kLCD_SenSet(UINT8 value);

__STATIC void
dispOpPowerOn(
	void
)
{
	UINT8 i;
	//here is a mark to reset LCM
	sp1kLCD_SenSet(1);		
	DELAY_1ms();    // Delay 1ms
	sp1kLCD_SenSet(0);	
	DELAY_1ms();
	sp1kLCD_SenSet(1);	
	DELAY_1ms();
	// Delay 50 ms  

	/* set clk and type. */
	dispParaSet(DISP_PARA_CLK_CFG, CLK_SRC, CLK_DIVNX, CLK_DIV1X, 0, 0);
	dispParaSet(DISP_PARA_UPS_CLK_PHASE, UPS_CLK_PHASE, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_DEVICE_TYPE, DEV_TYPE, 0, 0, 0, 0);

	/* set vh timing and format */
	dispParaSet(DISP_PARA_DEVICE_TOTAL_REGION, HPIXEL, VLINE, HSYNCW, VSYNCW, 0);
	dispParaSet(DISP_PARA_DEVICE_ACTIVE_REGION, PNLH0, PNLV0, PNLH1, PNLV1, 0);
	dispParaSet(DISP_PARA_INTERLACE_CFG, DISP_PROGRESSIVE, 0, 0, 0, 0);

	/* set lcm interface. */
	dispParaSet(DISP_PARA_LCM_CMD_BUS_TYPE, BUS_TYPE, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_CMD_BIT_WIDTH, BIT_WIDTH, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_CMD_PULSE_WIDTH, PULSE_ACT, PULSE_RCV, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_CMD_ACTIVE_LEVEL, CS0_ACT, A0_CMD, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_DATA_FORMAT, DATA_FMT, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_RGB666_PACK_ENABLE, RGB666_PACK, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_RGB666_FORMAT_10_ENABLE, RGB666_FMT_10, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_PIXEL_ALIGN, PIXEL_ALIGN, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_COLOR_PACKAGE, COLOR_PACKAGE, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_SWITCH_G_ENABLE, SWITCH_G, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_CHANGE_RB_ENABLE, CHANGE_RB, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_ONE_HALF_PIXEL_ENABLE, ONE_HALF_PIXEL, 0, 0, 0, 0);
	dispParaSet(DISP_PARA_LCM_DITHER_ENABLE, DITHER, 0, 0, 0, 0);

	sp1kGpioByteFuncSet(SP1K_GPIO_BYTE_P1,0x01,0x01);
	sp1kGpioByteDirSet(SP1K_GPIO_BYTE_P1,0x01,0x01);
	sp1kGpioByteOutSet(SP1K_GPIO_BYTE_P1,0x01,0x00);
	for(i=0;i<100;i++)
		DELAY_1ms();
	sp1kGpioByteOutSet(SP1K_GPIO_BYTE_P1,0x01,0x01);
	for(i=0;i<50;i++)
		DELAY_1ms();
	
	/* send lcm command. */
	dispLcmCmdTableSend(dispPwrOnCmdTbl);
	//	sp1kGpioByteFuncSet(SP1K_GPIO_BYTE_GEN1,0x80,0x80);
	//sp1kGpioByteDirSet(SP1K_GPIO_BYTE_GEN1,0x80,0x80);
	//sp1kGpioByteOutSet(SP1K_GPIO_BYTE_GEN1,0x80,0x80);
	// sp1kGpioByteFuncSet(SP1K_GPIO_BYTE_P1,0x08,0x08);
	// sp1kGpioByteDirSet(SP1K_GPIO_BYTE_P1,0x08,0x08);
	// sp1kGpioByteOutSet(SP1K_GPIO_BYTE_P1,0x08,0x08);

		 printf("zhenglei 8230s LCD Init OK 15:50\n");  
}

/**
 * @brief	operating function to power off device.
 * @param	None.
 * @retval	None.
 * @see
 * @author	Matt Wang
 * @since	2008-06-16
 * @todo	N/A
 * @bug		N/A
*/
__STATIC void
dispOpPowerOff(
	void
)
{
	/* send lcm command. */
	dispLcmCmdTableSend(dispPwrOffCmdTbl);
	//sp1kGpioByteFuncSet(SP1K_GPIO_BYTE_GEN1,0x80,0x80);
	//sp1kGpioByteDirSet(SP1K_GPIO_BYTE_GEN1,0x80,0x80);
	//sp1kGpioByteOutSet(SP1K_GPIO_BYTE_GEN1,0x80,0x00);
	sp1kGpioByteFuncSet(SP1K_GPIO_BYTE_P1,0x08,0x08);
	sp1kGpioByteDirSet(SP1K_GPIO_BYTE_P1,0x08,0x08);
	sp1kGpioByteOutSet(SP1K_GPIO_BYTE_P1,0x08,0x08);

}


